<template>
  <div>
    <el-card shadow="hover">
      <!-- 提交按钮 -->
      <template #header>
        <el-button
          type="primary"
          :icon="Plus"
          @click="showDialog({ tmName: '', logoUrl: '' })"
          v-has="'btn.Trademark.add'"
          >添加</el-button
        >
      </template>
      <!-- 表格 -->
      <el-table :data="tableData" border v-loading="loading">
        <el-table-column label="序号" width="80" type="index" align="center" />
        <el-table-column prop="tmName" label="品牌名称" />
        <el-table-column label="品牌LOGO">
          <!-- row: 当前行数据对象 -->
          <template v-slot="{ row, $index }">
            <el-image
              :src="row.logoUrl"
              style="width: 100px; height: 60px"
            ></el-image>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ row, $index }">
            <el-button
              type="warning"
              size="small"
              :icon="Edit"
              v-has="'btn.Trademark.update'"
              @click="showDialog(row)"
            ></el-button>
            <el-button
              type="danger"
              size="small"
              :icon="Delete"
              @click="removeList(row)"
              v-has="'btn.Trademark.remove'"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <!-- @current-change&@size-change 是element封装的事件配合v-model 监听数据改变 重新发送请求 -->
      <el-pagination
        style="margin-top: 20px"
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :total="total"
        :page-sizes="[3, 6, 9]"
        layout="prev, pager, next ,jumper, ->,sizes,total"
        @current-change="getList"
        @size-change="getList"
      />
      <!-- 添加修改的弹框 -->
      <el-dialog
        v-model="isShowDialog"
        :title="trademarkdFrom.id ? '修改品牌' : '添加品牌'"
      >
        <el-form
          :model="trademarkdFrom"
          label-width="140px"
          ref="ruleFormRef"
          :rules="rules"
        >
          <el-form-item label="品牌名称" prop="tmName">
            <el-input
              v-model="trademarkdFrom.tmName"
              autocomplete="off"
              placeholder="请输入品牌名称"
              style="width: 300px"
            />
          </el-form-item>
          <el-form-item label="品牌LOGO" prop="logoUrl">
            <el-upload
              class="avatar-uploader"
              :action="`${BASE_URL}/admin/product/fileUpload`"
              :show-file-list="false"
              :on-success="handleAvatarSuccess"
              :before-upload="beforeAvatarUpload"
            >
              <img
                v-if="trademarkdFrom.logoUrl"
                :src="trademarkdFrom.logoUrl"
                class="avatar"
              />
              <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
              <template #tip>
                <div class="el-upload__tip">
                  只能上传jpg/png文件，且不超过50kb
                </div>
              </template>
            </el-upload>
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="resetForm(ruleFormRef)">取消</el-button>
            <el-button type="primary" @click="submitForm(ruleFormRef)">
              确认
            </el-button>
          </span>
        </template>
      </el-dialog>
    </el-card>
  </div>
</template>

<script lang="ts">
  import { defineComponent } from "vue";
  export default defineComponent({
    name: "Trademark",
  });
</script>
<script lang="ts" setup>
  import {
    ElMessage,
    ElMessageBox,
    type FormInstance,
    type FormRules,
    type UploadProps,
  } from "element-plus";
  import {
    deleteTrademarkdListApi,
    getTrademarkdPageListApi,
    postAddTrademarkdListApi,
    putTrademarkdListApi,
  } from "@/api/product/trademarkd";
  import type {
    trademarkdListModel,
    trademarkdItemModel,
  } from "@/api/product/model/trademarkdModel";
  import { Delete, Edit, Plus } from "@element-plus/icons-vue";
  import { ref, onMounted, reactive } from "vue";
  /*   **初始化渲染的页面**  */
  // 品牌列表
  const tableData = ref<trademarkdListModel>([]);
  // 当前页
  const currentPage = ref(1);
  // 每页条数
  const pageSize = ref(3);
  // 总条数
  const total = ref(0);
  // 加载loading
  const loading = ref(false);

  //获取列表请求
  const getList = async () => {
    loading.value = true;
    const result = await getTrademarkdPageListApi(
      currentPage.value,
      pageSize.value
    );
    tableData.value = result.records;
    total.value = result.total;
    loading.value = false;
  };

  //初始化获取数据
  onMounted(() => {
    getList();
  });

  /*   **添加修改的弹窗**  */
  //利用代理解决上传图片路径跨域问题
  const BASE_URL = import.meta.env.VITE_BASE_URL;
  //是否显示弹框
  const isShowDialog = ref(false);
  //初始化弹窗数据
  const trademarkdFrom = reactive<trademarkdItemModel>({
    tmName: "",
    logoUrl: "",
  });
  //给button添加事件
  const showDialog = (trademarkd: trademarkdItemModel) => {
    // 显示dialog
    isShowDialog.value = true;
    // 如果trademark有值, 更新trademarkForm显示到表单中
    // if (trademark) {  // 点击添加时, 传入一个空的trademark对象
    trademarkdFrom.id = trademarkd.id;
    trademarkdFrom.tmName = trademarkd.tmName;
    trademarkdFrom.logoUrl = trademarkd.logoUrl;

    //  手动清除校验错误信息:
    // 内部的校验操作是异步执行, 我们清除操作发生校验之前
    // formRef.value?.clearValidate()

    // 必须延迟执行校验操作, 让它在自动校验之后清除
    //第一种方法 宏任务
    setTimeout(() => {
      ruleFormRef.value?.clearValidate();
    }, 0);

    // 使用nextTick(微任务)  有问题
    // 原因: 校验的异步任务在当前nextTick微任务之后才执行
    // nextTick(() => {
    //   formRef.value?.clearValidate()
    // })

    // 使用2个嵌套的nextTick  可以
    // nextTick(() => {
    //   nextTick(() => {
    //     formRef.value?.clearValidate();
    //   });
    // });

    // 原因: 内部的异步校验是在点击回调执行完后, 启动微任务去校验的
    // 如果就一层nextTick, 回调是在校验之前执行的  => 没有效果
    // 如果是二层nextTick, 内层的回调就是在校验之后才执行  => 有效果
    // 如果直接使用定时器, 它使用的是宏任务, 在校验之后执行 => 肯定有效果
  };

  //上传图片 显示图片事件
  const handleAvatarSuccess: UploadProps["onSuccess"] = (
    response,
    uploadFile
  ) => {
    // trademarkdFrom.logoUrl = URL.createObjectURL(uploadFile.raw!); //会产生临时的url地址,后面无法再使用
    trademarkdFrom.logoUrl = response.data;

    // 清除logo的错误提示信息
    ruleFormRef.value?.clearValidate(["logoUrl"]);
  };
  //限制图片类型&大小
  const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
    if (rawFile.type !== "image/jpeg" && rawFile.type !== "image/png") {
      ElMessage.error("图片格式必须为jpg或png!");
      return false;
    } else if (rawFile.size / 1024 > 200) {
      ElMessage.error("图片大小不能大于200kb!");
      return false;
    }

    return true;
  };

  // 提交更新或者添加 事件
  const confirm = async () => {
    if (trademarkdFrom.id) {
      await putTrademarkdListApi(trademarkdFrom);
    } else {
      await postAddTrademarkdListApi(trademarkdFrom);
    }
    isShowDialog.value = false;
    getList();
    ElMessage.success(`${trademarkdFrom.id ? "修改" : "添加"}成功`);
  };

  // 表单校验
  const ruleFormRef = ref<FormInstance>();
  const rules = reactive<FormRules>({
    tmName: [
      {
        required: true,
        message: "必须填品牌名称!",
      },
      // { min: 2, max: 6, message: "请输入2~6个字的名称!", trigger: "blur" },
      {
        validator: validatePass,
      },
    ],
    logoUrl: [
      {
        required: true,
        message: "必须上传LOGO图片!",
        trigger: "blur",
      },
    ],
  });
  //自定义验证规则
  function validatePass(rule: any, value: any, callback: any) {
    if (value.length >= 2 && value.length <= 6) {
      callback();
    } else {
      callback("请输入2~6个字的名称!");
    }
  }
  //点击提交进行校验 校验成功就发送请求
  const submitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid) => {
      if (valid) {
        confirm();
      }
    });
  };
  // 点击取消 重置该表单
  const resetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    formEl.resetFields();
    isShowDialog.value = false;
  };

  /* 删除提示 */
  const removeList = (row: trademarkdItemModel) => {
    ElMessageBox.confirm(`确定删除${row.tmName}吗?`, "提示", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(async () => {
        await deleteTrademarkdListApi(row.id as number);
        ElMessage.success("删除成功！");

        if (tableData.value.length === 1) {
          // 将当前页码减一
          currentPage.value -= 1;
        }
        getList();
      })
      .catch((error) => {
        if (error === "cancel") {
          ElMessage({
            type: "info",
            message: "取消删除",
          });
        }
      });
  };
</script>

<style lang="scss" scoped>
  .avatar-uploader .avatar {
    width: 178px;
    // height: 178px;
    display: block;
  }
  .avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
  }

  .avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
  }

  .el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
  }
</style>
